#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

class Name_Fifo
{
public:
    Name_Fifo(const std::string path, const std::string name)
        : _Name(name), _Path(path)
    {
        umask(0);
        _fifoname = _Path + "/" + _Name;
        int ret = mkfifo(_fifoname.c_str(), 0666);
        if (ret == 0)
        {
            std::cout << "mkfifo success！\n"
                      << std::endl;
        }
        else
        {
            std::cout << "mkfifo fail!\n"
                      << std::endl;
            exit(1);
        }
    }
    ~Name_Fifo()
    {
        unlink(_fifoname.c_str());
    }

private:
    std::string _Path;
    std::string _Name;
    std::string _fifoname;
};

// 对指定命名管道进行的操作
class oper_fifo
{
public:
    oper_fifo(const std::string path, const std::string name)
        : _Path(path), _Name(name), _fd(-1)
    {
        _fifoname = _Path + "/" + _Name;
    }
    ~oper_fifo()
    {
    }
    void OpenForRead()
    {
        _fd = open(_fifoname.c_str(), O_RDONLY);
        if (_fd < 0)
        {
            std::cout << "open fifo failed!" << std::endl;
            exit(2);
        }
        else
        {
            std::cout << "open fifo success!" << std::endl;
        }
    }
    void OpenForWrite()
    {
        _fd = open(_fifoname.c_str(), O_WRONLY);
        if (_fd < 0)
        {
            std::cout << "open fifo failed!" << std::endl;
            exit(2);
        }
        else
        {
            std::cout << "open fifo success!" << std::endl;
        }
    }
    void Read()
    {
        // 具体的读取操作在这里定义
        while (true)
        {
            char rd_buffer[1024];
            int ret = read(_fd, rd_buffer, sizeof(rd_buffer) - 1);
            if (ret == 0)
            {
                // 读到了文件末尾表示写入端退出：
                std::cout << "write exit me too!" << std::endl;
                break;
            }
            else if (ret < 0)
            {
                std::cout << "read failed!" << std::endl;
            }
            else
            {
                rd_buffer[ret] = '0';
                std::cout << "Client say:" << rd_buffer << std::endl;
            }
        }
    }
    void Write()
    {
        // 具体的写入操作在这里定义
        while (1)
        {
            std::cout<<"Please Enter:"<<std::endl;
            std::string messager;
            int cnt = 1;
            pid_t id = getpid();
            std::getline(std::cin, messager);
            messager += (", message number: " + std::to_string(cnt++) + ", [" + std::to_string(id) + "]");
            int ret=write(_fd,messager.c_str(),messager.size());
        }
    }
    void Close()
    {
        if(_fd>0)
        {
            close(_fd);
        }
    }
private:
    std::string _Path;
    std::string _Name;
    std::string _fifoname;
    int _fd; // 命名管道的文件描述符
};